package com.dokimall.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.dokimall.cart.feign.SkuFeignService;
import com.dokimall.cart.interceptor.CartInterceptor;
import com.dokimall.cart.service.CartService;
import com.dokimall.cart.vo.Cart;
import com.dokimall.cart.vo.CartItem;
import com.dokimall.cart.vo.UserInfo;
import com.dokimall.cart.vo.skuItemInfo;
import com.dokimall.common.utils.R;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.util.comparator.ComparableComparator;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ClassName: CartServiceImpl
 * @Description:
 * @Author
 * @Date 2021/10/24
 * @Version 1.0
 */

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    SkuFeignService skuFeignService;
    @Autowired
    ThreadPoolExecutor executor;

    public static final String CART_PERFIX= "dokimall:cart:";

    @Override
    public CartItem addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String res = (String) cartOps.get(skuId.toString());
        if(StringUtils.isEmpty(res)){
            // 购物车无原商品，新增商品
            CartItem cartItem = new CartItem();
            //开启线程池用异步的方式来处理，效率更快
            CompletableFuture<Void> getSkuInfoTask = CompletableFuture.runAsync(() -> {
                // 调用远程方法查询商品信息
                R r = skuFeignService.getSkuInfo(skuId);
                skuItemInfo skuInfo = r.getData("skuInfo", new TypeReference<skuItemInfo>() {
                });
                cartItem.setCheck(true);
                cartItem.setConut(num);
                cartItem.setImage(skuInfo.getSkuDefaultImg());
                cartItem.setPrice(skuInfo.getPrice());
                cartItem.setTitle(skuInfo.getSkuTitle());
                cartItem.setSkuId(skuId);
            }, executor);

            CompletableFuture<Void> skuAttrTask = CompletableFuture.runAsync(() -> {
                //获得对应商品的属性信息
                List<String> strings = skuFeignService.stringListSkuAttr(skuId);
                cartItem.setSkuAttr(strings);
            },executor);

            CompletableFuture.allOf(getSkuInfoTask,skuAttrTask).get();
            String s = JSON.toJSONString(cartItem);
            cartOps.put(String.valueOf(skuId),s);
            return cartItem;
        }else {
            // 原来购物车已经有该商品，在原来的数量上添加即可
            CartItem cartItem = JSON.parseObject(res, CartItem.class);
            cartItem.setConut(cartItem.getConut()+num);
            cartOps.put(String.valueOf(skuId),JSON.toJSONString(cartItem));
            return cartItem;
        }


    }
    @Override
    // 更改选择框状态
    public void checkItem(Long skuId, Integer check) {
        BoundHashOperations<String, Object, Object> boundHashOperations = getCartOps();
        CartItem cartItem = getCartById(skuId);
        cartItem.setCheck(check==1);
        String string = JSON.toJSONString(cartItem);
        boundHashOperations.put(skuId.toString(),string);
    }

    @Override
    public void changeItemNum(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> boundHashOperations = getCartOps();
        CartItem cartItem = getCartById(skuId);
        cartItem.setConut(num);
        String string = JSON.toJSONString(cartItem);
        boundHashOperations.put(skuId.toString(),string);
    }

    @Override
    public void deleteItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        cartOps.delete(skuId.toString());
    }

    @Override
    public List<CartItem> getCheckedItem() {
        UserInfo userInfo = CartInterceptor.threadLocal.get();
        if(userInfo.getUserId()!=null){
            Long userId = userInfo.getUserId();
            List<CartItem> cartItems = getCartItems(CART_PERFIX + userId);
            List<CartItem> collect = cartItems.stream().filter(item -> {
                return item.getCheck();
            }).map(item -> {
                item.setPrice(skuFeignService.getNewPrice(item.getSkuId()));
                BigDecimal TotalPrice = item.getPrice().multiply(new BigDecimal(item.getConut()));
                item.setTotalPrice(TotalPrice);
                return item;
            }).collect(Collectors.toList());
            return collect;
        }else {
            return null;
        }

    }

    @Override
    public CartItem getCartById(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String res = (String) cartOps.get(skuId.toString());
        CartItem cartItem = JSON.parseObject(res, CartItem.class);
        return cartItem;
    }

    @Override
    public Cart getCart(UserInfo userInfo) throws ExecutionException, InterruptedException {
        Cart cart = new Cart();
        if(userInfo.getUserId()!=null){
            // 登录状态
            // 先查看临时购物车有没有东西，有的话需要添加到登录用户的购物车里
            String userKey = CART_PERFIX + userInfo.getUserKey();
            List<CartItem> cartItems = getCartItems(userKey);
            if(cartItems!=null && cartItems.size()>0){
                // 临时购物车有东西，需要添加到登录用户的购物车里
                for (CartItem cartItem : cartItems) {
                    Long skuId = cartItem.getSkuId();
                    Integer conut = cartItem.getConut();
                    addToCart(skuId,conut);
                }
                // 清空临时购物车的东西
                clearCart(userKey);
            }
            // 获取已登录的购物车
            List<CartItem> cartItemList = getCartItems(CART_PERFIX + userInfo.getUserId());
            cart.setItems(cartItemList);
        }else {
            // 未登录状态
            String userKey = CART_PERFIX + userInfo.getUserKey();
            List<CartItem> cartItems = getCartItems(userKey);
            cart.setItems(cartItems);
        }
        return cart;
    }

    @Override
    // 清空购物车
    public void clearCart(String userKey) {
        redisTemplate.delete(userKey);
    }



    // 获取购物车
    private List<CartItem> getCartItems(String userKey) { // userKey 记得在放入前加入前缀！！CART_PERFIX
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(userKey);
        List<Object> values = boundHashOps.values();
        if (values!=null && values.size()>0){
            List<CartItem> collect = values.stream().map((obj) -> {
                CartItem cartItem = JSON.parseObject(obj.toString(), CartItem.class);
                return cartItem;
            }).collect(Collectors.toList());
            return collect;
        }else {
            return null;
        }
    }

    public BoundHashOperations<String, Object, Object> getCartOps() {
        // 判断是否为登录状态
        UserInfo userInfo = CartInterceptor.threadLocal.get();
        String cartName = "";
        if(userInfo.getUserId()!=null){
            // 登录状态
            cartName = CART_PERFIX + userInfo.getUserId();
        }else {
            // 未登录状态
            cartName = CART_PERFIX + userInfo.getUserKey();

        }
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(cartName);
        return boundHashOps;
    }
}
